package com.aos.config;

import com.aos.service.UserServiceDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
@Configuration
public class OAuth2Config {

    //@EnableAuthorizationServer开启授权服务:
    // 需配置ClientDetailsServiceConfigurer，AuthorizationServerEndpointsConfigurer，AuthorizationServerSecurityConfigurer
    @Configuration
    @EnableAuthorizationServer
    protected  class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {


        @Autowired
        @Qualifier("authenticationManagerBean")
        private AuthenticationManager authenticationManager;

        //Redis配置
        @Autowired
        private RedisConnectionFactory connectionFactory;

        //内存存储
        //private TokenStore tokenStore = new InMemoryTokenStore();

        //数据库存储
        //JdbcTokenStore tokenStore=new JdbcTokenStore(dataSource);

        //Redis存储
        @Bean
        public TokenStore tokenStore() {
            RedisTokenStore redis = new RedisTokenStore(connectionFactory);
            return redis;
        }



        @Autowired
        private UserServiceDetail userServiceDetail;

        //配置客户端信息（所有需要通过OAuth2校验的客户端信息都需配置）
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

            clients.inMemory()	//将客户端信息存储在内存中
                    .withClient("uaa-service-gov")//创建了一个clientId为uaa-service-gov的客户端
                    .secret("123456")//客户端密码
                    .authorizedGrantTypes("password","client_credentials")//客户端可以使用的授权类型
                    .scopes("server")//范围
                    //.accessTokenValiditySeconds(6*3600) //6小时过期
                    .accessTokenValiditySeconds(12*3600) //12小时过期
                    /********************************本地测试用客户端*******************************/
                    .and()
                    .withClient("service-demo")//本地测试用客户端
                    .secret("67890")
                    .authorizedGrantTypes("password","client_credentials")
                    .scopes("server")
                    .accessTokenValiditySeconds(12*3600)
                    /**********************************权限服务***********************************/
                    .and()
                    .withClient("user-service-gov")
                    .secret("88888")
                    .authorizedGrantTypes("password","client_credentials")
                    .scopes("server")
                    .accessTokenValiditySeconds(12*3600)
                    /***************************************报名助手********************************/
                    .and()
                    .withClient("axschoolweb")//报名助手
                    .secret("88888")
                    .authorizedGrantTypes("password","client_credentials")
                    .scopes("server")
                    .accessTokenValiditySeconds(12*3600);//12小时过期;

        }

        //存储Token
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
            endpoints
                    .authenticationManager(authenticationManager)
                    .tokenStore(tokenStore())//token存储方式
                    .userDetailsService(userServiceDetail);
        }

        //获取Token并校验
        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
            oauthServer
                    .tokenKeyAccess("permitAll()")
                    .checkTokenAccess("isAuthenticated()")
                    .allowFormAuthenticationForClients(); //主要是让/oauth/token支持client_id以及client_secret作登录认证
            // .checkTokenAccess("permitAll()");
        }
    }


    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            //resourceId 用于分配给可授予的clientId
            //stateless  标记以指示在这些资源上仅允许基于令牌的身份验证
            resources.resourceId("uaa-service-gov" ).stateless(true);
            resources.resourceId("user-service-gov" ).stateless(true);
            resources.resourceId("axschoolweb" ).stateless(true);
            resources.resourceId("service-demo" ).stateless(true);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http.authorizeRequests()
                    //.authorizeRequests().anyRequest().authenticated()
//                    .antMatchers("/entry/check","/user/synchro","/oauth/token",
//                            "/entry/delete","/oauth/revoke-token","/entry/dddd",
//                            "/user/role","/user/user-role","/*swagger-ui.*").permitAll()
                    .antMatchers("/**").permitAll()
                    .anyRequest().authenticated();
            http.csrf().disable();
            // @formatter:on
        }

        //销毁Token
//        @FrameworkEndpoint
//        public class RevokeTokenEndpoint {
//
//            @Autowired
//            @Qualifier("consumerTokenServices")
//            ConsumerTokenServices consumerTokenServices;
//
//            @RequestMapping(value = "/oauth/delete",method = RequestMethod.DELETE)
//            @ResponseBody
//            public String revokeToken(@RequestParam(value="access_token",required=false) String access_token ) {
//                System.out.println("===============开始注销===============");
//                System.out.println("========access_token:" + access_token);
//                if (consumerTokenServices.revokeToken(access_token)){
//                    return "注销成功";
//                }else{
//                    return "注销失败";
//                }
//            }
//        }

    }
}
